import { getAvailablePort, getLanIpAddresses } from "../../util/net-utils.ts";
import { fileShareService } from "./service.ts";
import { type FastifyInstance } from "fastify";
import path from "node:path";
import fsp from "node:fs/promises";
import type { LanShareServerStatus, ShareFileInfo } from "@common/lan-share-types.ts";

/**
 * 文件分享http服务
 */
export const lanShareServer = (() => {
  const defaultPort = 5620;
  let server: FastifyInstance | null = null;
  let serverPort = defaultPort;

  /**
   * 启动服务
   */
  async function start() {
    const fastify = await import("fastify");

    serverPort = await getAvailablePort(defaultPort);
    server = fastify.fastify({ logger: false, return503OnClosing: false, forceCloseConnections: true });

    // 静态资源
    const fastifyStatic = await import("@fastify/static");
    server.register(fastifyStatic.default, {
      root: "/path/to/public",
    });

    // api接口
    server.get("/list-files", async request => {
      const fileList = await fileShareService.getSharedFileList();
      const query = request.query as Record<string, string>;
      const folderId: string | undefined = query.parentId;
      if (!folderId) {
        return fileList;
      }
      const subPath: string = query.path || "/";
      const folder = fileList.find(it => it.id === folderId);
      if (!folder) {
        return [];
      }
      const targetPath = path.join(folder.path, subPath);
      const subFiles = await fsp.readdir(targetPath, { withFileTypes: true });
      return subFiles
        .filter(it => it.isFile() || it.isDirectory())
        .map<ShareFileInfo>(it => ({
          id: it.name,
          type: it.isFile() ? "file" : "dir",
          path: path.join(targetPath, it.name),
        }));
    });

    await server.listen({ port: serverPort, host: "0.0.0.0" });

    await fileShareService.ensureDataDir();
    await fileShareService.loadSharedFiles();

    console.log(`[file-share-server] started on port: ${serverPort}`);
    return getStatus();
  }

  /**
   * 关闭服务
   */
  async function close() {
    if (server) {
      await server.close();
      server = null;
      console.log(`[file-share-server] closed`);
    }

    return getStatus();
  }

  /**
   * 获取服务状态
   */
  async function getStatus(): Promise<LanShareServerStatus> {
    return {
      hosts: getLanIpAddresses(),
      port: serverPort,
      running: server != null,
    };
  }

  return {
    start: start,
    close: close,
    getStatus: getStatus,
  };
})();
